package com.ruoyi.web.ydz.service.impl;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.web.ydz.domain.AttachFile;
import com.ruoyi.web.ydz.domain.Invitation;
import com.ruoyi.web.ydz.domain.InvitationCollect;
import com.ruoyi.web.ydz.domain.Reply;
import com.ruoyi.web.ydz.mapper.InvitationMapper;
import com.ruoyi.web.ydz.mapper.ReplyMapper;
import com.ruoyi.web.ydz.service.IAttachFileService;
import com.ruoyi.web.ydz.service.IInvitationLikeService;
import com.ruoyi.web.ydz.service.IInvitationService;
import com.ruoyi.web.ydz.util.areaUtil.AreaUtil;
import com.ruoyi.web.ydz.util.sensitiveFilter.FileToList;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

import static com.ruoyi.common.utils.PageUtils.startPage;

/**
 * 论坛提问Service业务层处理
 *
 * @author ruoyi
 * @date 2024-10-29
 */
@Service
public class InvitationServiceImpl implements IInvitationService {
    @Resource
    private InvitationMapper invitationMapper;

    @Resource
    private AreaUtil areaUtil;

    @Resource
    private IInvitationLikeService invitationLikeService;

    @Resource
    private ReplyMapper replyMapper;

    @Resource
    private ReplyLikeServiceImpl replyLikeService;

    @Resource
    private FileToList fileToList;

    @Resource
    private InvitationCollectServiceImpl invitationCollectService;

    @Resource
    private IAttachFileService AttachFileService;

    /**
     * 查询论坛提问
     *
     * @param id 论坛提问主键
     * @return 论坛提问
     */
    @Override
    public Invitation selectInvitationById(Long id) {
        Invitation invitation = invitationMapper.selectInvitationById(id);

        /*
         * 如果当前用户身份不是管理员
         * 则无法查看封禁帖子及回复
         * */
        Boolean isAdmin = false;
        SysUser user = SecurityUtils.getLoginUser().getUser();
        List<SysRole> roles = user.getRoles();
        if (!Objects.isNull(roles)) {
            isAdmin = roles.stream()
                    .anyMatch(bean -> bean.getRoleId().longValue() == 100) ? false : true;
        } else {
            isAdmin = false;
        }

        /*当前帖子为null 返回null
         * 当前帖子被封禁 且 当前用户为普通用户 返回null
         * */
        if (Objects.isNull(invitation) || ("1".equals(invitation.getBan()) && !isAdmin)) {
            return null;
        }

        /*判断此帖子是否为当前用户所属*/
        if (user.getUserId().longValue() == invitation.getUserId().longValue()){
            invitation.setIsOwner(true);
        }else {
            invitation.setIsOwner(false);
        }

        /*获取redis中点赞总数*/
        HashMap<String, Object> map = invitationLikeService.getinvitationLikes(invitation.getId());
        if (!Objects.isNull(map.get("likesCount"))) {
            invitation.setLikeCount(Long.parseLong(String.valueOf(map.get("likesCount"))));
        }

        /*获取总收藏数*/
        Long invitationCollectCount = invitationCollectService.getInvitationCollectCount(invitation.getId());
        invitation.setCollectCount(Objects.isNull(invitationCollectCount) ? 0 : invitationCollectCount);

        /*判断当前帖子用户是否点赞或收藏*/
        Long userId = user.getUserId();
        boolean memberOfSet = fileToList.isMemberOfSet("Invitation:InvitationLikesUser:" + invitation.getId(), "\"" + userId + "\"");
        invitation.setIsLike(memberOfSet);

        InvitationCollect invitationCollect = new InvitationCollect();
        invitationCollect.setInvitationId(invitation.getId());
        invitationCollect.setUserId(userId);
        invitationCollect.setStatus(0);
        List<InvitationCollect> invitationCollects = invitationCollectService.selectInvitationCollectList(invitationCollect);
        invitation.setIsCollect(!(Objects.isNull(invitationCollects) || invitationCollects.size() <= 0));

        /*获取当前帖子下的 全部回复*/
        Reply requestreply = new Reply();
        requestreply.setInvitationId(invitation.getId());
        if (!isAdmin) {
            requestreply.setReplyBan("0");
        }
        List<Reply> anyReply = replyMapper.selectReplyList(requestreply);

        /*获取总评论数*/
        invitation.setReplyCount(Objects.isNull(anyReply) ? 0l : (isAdmin ? (long) anyReply.size() : anyReply.stream()
                .filter(reply -> "0".equals(reply.getReplyBan()))
                .count()));

        /*获取当前帖子所属图片*/
        AttachFile attachFile = new AttachFile();
        attachFile.setSourceId(invitation.getId());
        attachFile.setFileClass("03");
        List<AttachFile> attachFiles = AttachFileService.selectAttachFileList(attachFile);
        invitation.setAttachFiles(attachFiles);

        // 递归处理所有子集
        List<Reply> result = new ArrayList<>();
        anyReply.forEach(item -> {
            // 获取当前回复下的点赞数及当前用户是否点赞
            boolean isLike = fileToList.isMemberOfSet("Reply:ReplyLikesUser:" + invitation.getId() + ":" + item.getId(), "\"" + userId + "\"");
            item.setIsLike(isLike);
            HashMap<String, Object> replyLikeCountmap = replyLikeService.getReplyLikes(invitation.getId(), item.getId());
            if (!Objects.isNull(replyLikeCountmap.get("likesCount"))) {
                item.setReplyLikeCount(Long.parseLong(String.valueOf(replyLikeCountmap.get("likesCount"))));
            }

            if (user.getUserId().longValue() == item.getUserId().longValue()){
                item.setIsOwner(true);
            }else {
                item.setIsOwner(false);
            }

            if (Objects.isNull(item.getPid())) result.add(item);
        });

        /*只循环父级*/
        for (int i = 0; i < result.size(); i++) {
            addChildReplies(result.get(i), anyReply, result.get(i));
            // 获取当前评论下的所有评论count
            HashMap<String, Object> paraMap = new HashMap<>();
            paraMap.put("replyId", result.get(i).getId());

            if (!isAdmin) {
                paraMap.put("isBan", 0);
            }

            Long replyCountByReplyId = replyMapper.getReplyCountByReplyId(paraMap);
            result.get(i).setReplyCount(Objects.isNull(replyCountByReplyId) ? 0 : replyCountByReplyId);

        }

        invitation.setReplies(result);
        return invitation;
    }

    /*递归获取两条的回复*/
    public void addChildReplies(Reply parentReply, List<Reply> replies, Reply bean) {
        for (Reply reply : replies) {
            if (!Objects.isNull(bean.getChildReply()) && bean.getChildReply().size() >= 2) break;
            if (Objects.isNull(reply.getPid())) continue;
            if (reply.getPid().longValue() == parentReply.getId().longValue()) {
                if (Objects.isNull(parentReply.getChildReply())) {
                    parentReply.setChildReply(new ArrayList<>());
                }
                bean.getChildReply().add(reply);
                // 递归查找子回复
                addChildReplies(reply, replies, bean);
            }
        }
    }

    /*递归获取全部的回复*/
    public void addChildRepliesAny(Reply parentReply, List<Reply> replies, Reply bean) {
        for (Reply reply : replies) {
            if (Objects.isNull(reply.getPid())) continue;
            if (reply.getPid().longValue() == parentReply.getId().longValue()) {
                if (Objects.isNull(parentReply.getChildReply())) {
                    parentReply.setChildReply(new ArrayList<>());
                }
                bean.getChildReply().add(reply);
                // 递归查找子回复
                addChildRepliesAny(reply, replies, bean);
            }
        }
    }

    /**
     * 查询论坛提问列表
     *
     * @param invitation 论坛提问
     * @return 论坛提问
     */
    @Override
    public List<Invitation> selectInvitationList(Invitation invitation) {
        startPage();

        /*
         * 如果当前用户身份不是管理员
         * 则查询自身的用药提醒
         * */
        SysUser user = SecurityUtils.getLoginUser().getUser();
        List<SysRole> roles = user.getRoles();
        if (!Objects.isNull(roles)) {
            roles.forEach(bean -> {
                if (100 == bean.getRoleId().longValue()) {
                    invitation.setUserId(user.getUserId());
                }
            });
        } else {
            invitation.setUserId(user.getUserId());
        }

        List<Invitation> invitations = invitationMapper.selectInvitationList(invitation);

        if (!Objects.isNull(invitations)) {
            invitations.forEach(bean -> {
                /*获取redis中点赞总数*/
                HashMap<String, Object> map = invitationLikeService.getinvitationLikes(bean.getId());
                if (!Objects.isNull(map.get("likesCount"))) {
                    bean.setLikeCount(Long.parseLong(String.valueOf(map.get("likesCount"))));
                }

                /*获取总评论数*/
                Long replyCount = replyMapper.getReplyCount(bean.getId());
                bean.setReplyCount(replyCount);

                /*获取当前帖子所属图片*/
                AttachFile attachFile = new AttachFile();
                attachFile.setSourceId(bean.getId());
                attachFile.setFileClass("03");
                List<AttachFile> attachFiles = AttachFileService.selectAttachFileList(attachFile);
                bean.setAttachFiles(attachFiles);
            });
        }

        return invitations;
    }

    @Override
    public List<Invitation> getInvitationList(Invitation invitation) {

        AjaxResult ajaxResult = new AjaxResult();
        List<Invitation> invitations = null;
        try {
            invitation.setBan("0");
            invitation.setStatus("1");

            startPage();
            invitations = invitationMapper.selectInvitationList(invitation);

            /*查询论坛下的点赞和回复*/
            if (!Objects.isNull(invitations)) {
                invitations.forEach(bean -> {

                    /*获取redis中点赞总数*/
                    HashMap<String, Object> map = invitationLikeService.getinvitationLikes(bean.getId());
                    if (!Objects.isNull(map.get("likesCount"))) {
                        bean.setLikeCount(Long.parseLong(String.valueOf(map.get("likesCount"))));
                    }

                    /*获取总评论数*/
                    Long replyCount = replyMapper.getReplyCount(bean.getId());
                    bean.setReplyCount(replyCount);

                    /*获取总收藏数*/
                    Long invitationCollectCount = invitationCollectService.getInvitationCollectCount(bean.getId());
                    bean.setCollectCount(Objects.isNull(invitationCollectCount) ? 0 : invitationCollectCount);

                    /*判断当前帖子用户是否点赞或收藏*/
                    SysUser user = SecurityUtils.getLoginUser().getUser();
                    Long userId = user.getUserId();
                    boolean memberOfSet = fileToList.isMemberOfSet("Invitation:InvitationLikesUser:" + bean.getId(), "\"" + userId + "\"");
                    bean.setIsLike(memberOfSet);

                    InvitationCollect invitationCollect = new InvitationCollect();
                    invitationCollect.setInvitationId(bean.getId());
                    invitationCollect.setUserId(userId);
                    invitationCollect.setStatus(0);
                    List<InvitationCollect> invitationCollects = invitationCollectService.selectInvitationCollectList(invitationCollect);
                    bean.setIsCollect(!(Objects.isNull(invitationCollects) || invitationCollects.size() <= 0));

                    /*判断此帖子是否为当前用户所属*/
                    if (user.getUserId().longValue() == bean.getUserId().longValue()){
                        bean.setIsOwner(true);
                    }else {
                        bean.setIsOwner(false);
                    }

                    /*获取当前帖子所属图片*/
                    AttachFile attachFile = new AttachFile();
                    attachFile.setSourceId(bean.getId());
                    attachFile.setFileClass("03");
                    List<AttachFile> attachFiles = AttachFileService.selectAttachFileList(attachFile);
                    bean.setAttachFiles(attachFiles);

                    /*获取当前帖子下的 全部回复*/
                    /*Reply requestreply = new Reply();
                    requestreply.setInvitationId(bean.getId());
                    List<Reply> anyReply = replyMapper.selectReplyList(requestreply);

                    *//*递归处理所有子集*//*
                    List<Reply> result = new ArrayList<>();
                    anyReply.forEach(item -> {
                        *//*获取当前回复下的点赞数及当前用户是否点赞*//*
                        boolean isLike = fileToList.isMemberOfSet("Reply:ReplyLikesUser:" + bean.getId() + ":" + item.getId() ,"\"" + userId + "\"");
                        item.setIsLike(isLike);
                        HashMap<String, Object> replyLikeCountmap = replyLikeService.getReplyLikes(bean.getId(),item.getId());
                        if (!Objects.isNull(replyLikeCountmap.get("likesCount"))) {
                            item.setReplyLikeCount(Long.parseLong(String.valueOf(replyLikeCountmap.get("likesCount"))));
                        }

                        if (Objects.isNull(item.getPid())) result.add(item);
                    });

                    result.forEach(item -> {
                        addChildReplies(item, anyReply, item);
                        *//*获取当前评论下的所有评论count*//*
                        Long replyCountByReplyId = replyMapper.getReplyCountByReplyId(item.getId());
                        item.setReplyCount(Objects.isNull(replyCountByReplyId) ? 0 : replyCountByReplyId);
                    });

                    bean.setReplies(result);*/

                });
            }
            ajaxResult.put("code", 200);
            ajaxResult.put("msg", "查询成功");
            ajaxResult.put("data", invitations);
        } catch (Exception e) {
            e.printStackTrace();
            ajaxResult.put("code", 500);
            ajaxResult.put("msg", "查询失败，请联系管理员");
            ajaxResult.put("data", e.getMessage());
        }

        return invitations;
    }

    /**
     * 新增论坛提问
     *
     * @param invitation 论坛提问
     * @return 结果
     */
    @Override
    public int insertInvitation(Invitation invitation, HttpServletRequest request) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        invitation.setCreateTime(DateUtils.getNowDate());
        invitation.setCreateBy(user.getUserName());
        invitation.setCreateName(user.getNickName());
        invitation.setUpdateTime(DateUtils.getNowDate());
        invitation.setUpdateBy(user.getUserName());
        invitation.setUpdateName(user.getNickName());

        invitation.setUserId(user.getUserId());

        /*获取ip*/
        HashMap clientIp = areaUtil.getClientIp(request);
        invitation.setUserIp(Objects.isNull(clientIp.get("ip")) ? "未知" : String.valueOf(clientIp.get("ip")));
        invitation.setUserArea(Objects.isNull(clientIp.get("area")) ? "未知" : String.valueOf(clientIp.get("area")));

        int i = invitationMapper.insertInvitation(invitation);

        /*保存帖子相关图片*/
        if (!Objects.isNull(invitation.getAttachFiles())){
            invitation.getAttachFiles().forEach(bean -> {
                bean.setSourceId(invitation.getId());
                bean.setFileClass("03");
                AttachFileService.insertAttachFile(bean);
            });
        }

        return  i;
    }

    /**
     * 修改论坛提问
     *
     * @param invitation 论坛提问
     * @return 结果
     */
    @Override
    public int updateInvitation(Invitation invitation) {

        SysUser user = SecurityUtils.getLoginUser().getUser();
        invitation.setUpdateTime(DateUtils.getNowDate());
        invitation.setUpdateBy(user.getUserName());
        invitation.setUpdateName(user.getNickName());

        if (!Objects.isNull(invitation.getAttachFiles())){
            invitation.getAttachFiles().forEach(bean -> {
                if (Objects.isNull(bean.getId())){
                    bean.setFileClass("03");
                    bean.setSourceId(invitation.getId());
                    AttachFileService.insertAttachFile(bean);
                }else {
                    AttachFileService.updateAttachFile(bean);
                }
            });
        }

        return invitationMapper.updateInvitation(invitation);
    }

    /**
     * 批量删除论坛提问
     *
     * @param ids 需要删除的论坛提问主键
     * @return 结果
     */
    @Override
    public int deleteInvitationByIds(Long[] ids) {
        return invitationMapper.deleteInvitationByIds(ids);
    }

    /**
     * 删除论坛提问信息
     *
     * @param id 论坛提问主键
     * @return 结果
     */
    @Override
    public int deleteInvitationById(Long id) {
        return invitationMapper.deleteInvitationById(id);
    }

    @Override
    public AjaxResult examineInvitation(Invitation invitation) {
        AjaxResult ajaxResult = new AjaxResult();
        SysUser user = SecurityUtils.getLoginUser().getUser();

        if (Objects.isNull(invitation.getId())) {
            ajaxResult.put("code", 200);
            ajaxResult.put("msg", "无操作对象");
            return ajaxResult;
        }

        if (!Objects.isNull(invitation.getStatus()) && "1".equals(invitation.getStatus())) {
            invitation.setStatusTime(DateUtils.getNowDate());
        } else if (!Objects.isNull(invitation.getExamine()) && "1".equals(invitation.getExamine())) {
            invitation.setExamineBy(String.valueOf(user.getUserId()));
            invitation.setExamineTime(DateUtils.getNowDate());
        }

        invitationMapper.updateInvitation(invitation);
        ajaxResult.put("code", 200);
        ajaxResult.put("msg", "操作成功");

        return ajaxResult;
    }
}
